package com.px.service;

import com.mongodb.client.result.UpdateResult;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;


@Service
public class MongoServiceImpl<T> implements MongoService<T> {
    @Resource
    private MongoTemplate mongoTemplate;
    /**
     * 创建对象
     */
    public void save(T t) throws Exception {
        mongoTemplate.save(t);
    }

    /**
     * MongDb分页公共方法
     * @param clazz 实体类的class对象
     * @param pageSize 每页的数量
     * @param pageNum 当前的页数
     * @param query query是啥不知道赶紧去查下，相当于sql语句
     * @return
     */
    public List<T> pagination(Class<T> clazz, int pageSize, int pageNum, Query query) {
        long total = this.mongoTemplate.count(query, clazz);
        Integer pages = (int)Math.ceil((double)total / (double)pageSize);
        if (pageNum <= 0 || pageNum > pages) {
            pageNum = 1;
        }
        int skip = pageSize * (pageNum - 1);
        query.skip(skip).limit(pageSize);
        List<T> list = mongoTemplate.find(query, clazz);
        return list;
    }

    @Override
    public <T1> void dropCollection(Class<T1> entityClass) {
        mongoTemplate.dropCollection(entityClass);
    }



    /**
     * 根据条件查询集合对象
     * @param clazz
     * @param query
     * @param <T>
     * @return
     */
    @Override
    public <T> List<T> find(Class<T> clazz, Query query) throws Exception {
        return mongoTemplate.find(query, clazz);
    }

    /**
     * 查询一条记录
     * @param clazz
     * @param query
     * @param <T>
     * @return
     */
    @Override
    public <T> T findOne(Class<T> clazz, Query query) throws Exception {
        return mongoTemplate.findOne(query, clazz);
    }

    /**
     * 根据ID查询一个对象
     * @param clazz
     * @param id
     * @param <T>
     * @return
     */
    @Override
    public <T> T findById(Class<T> clazz, Object id) throws Exception {
        return mongoTemplate.findById(id, clazz);
    }

    /**
     * 根据属性查询对象
     * @param key
     * @param value     属性值
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T findByLong(String key, Long value, Class<T> clazz) throws Exception {
        Query query = new Query(Criteria.where(key).is(value));
        T t = mongoTemplate.findOne(query, clazz);
        return t;
    }

    /**
     * 根据属性查询对象
     * @param key
     * @param value
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T findByLong(String key, String value, Class<T> clazz) throws Exception {
        Query query = new Query(Criteria.where(key).is(value));
        T t = mongoTemplate.findOne(query, clazz);
        return t;
    }

    /**
     * 更新对象
     */
    public <T> Long updateFirst(Class<T> clazz, Query query,Update update) {
        //更新查询返回结果集的第一条
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, clazz);
        return updateResult.getModifiedCount();
        //更新查询返回结果集的所有
        // mongoTemplate.updateMulti(query,update,TestEntity.class);
    }

    /**
     * 根据条件查询总条数
     * @param clazz
     * @param query
     * @param <T>
     * @return
     */
    @Override
    public <T> long findCount(Class<T> clazz, Query query) throws Exception {
        return mongoTemplate.count(query, clazz);
    }

    /**
     * 删除对象
     * @param key
     * @param value
     * @param clazz
     */
    public void deleteByLong(String key, Long value, Class<T> clazz) throws Exception {
        Query query = new Query(Criteria.where(key).is(value));
        mongoTemplate.remove(query, clazz);
    }

    /**
     * 删除对象
     * @param key
     * @param value
     * @param clazz
     */
    public void deleteByString(String key, String value, Class<T> clazz) throws Exception {
        Query query = new Query(Criteria.where(key).is(value));
        mongoTemplate.remove(query, clazz);
    }

    /***
     * 删除对象
     * @param t
     * @return
     */
    public int delete(T t) {
        return (int) this.mongoTemplate.remove(t).getDeletedCount();
    }

    /**
     * 根据id删除
     *
     * @param id
     */
    public void deleteById(Integer id) {
        Criteria criteria = Criteria.where("_id").is(id);
        if (null != criteria) {
            Query query = new Query(criteria);
            T obj = (T) this.mongoTemplate.findOne(query, this.getClass());
            if (obj != null) {
                this.delete(obj);
            }
        }
    }

}
